home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / system / ifp1s158.zip / INFOPLUS.ASM < prev    next >
Assembly Source File  |  1993-06-26  |  33KB  |  1,045 lines

  1. ;--------------------------------------------------------------------
  2. ;
  3. ;       INFOPLUS.ASM
  4. ;
  5. ;       Version 1.57
  6. ;
  7. ;       Eleven subprograms used by INFOPLUS.PAS:
  8. ;
  9. ;               CPUID           - identifies host CPU and NDP (if
  10. ;                                       any)
  11. ;               DISKREAD        - reads absolute sectors from disk
  12. ;               LONGCALL        - calls a routine using a CALL FAR
  13. ;               ATIINFO         - for accessing ATI VGAWonder cards
  14. ;               ALTINTR         - calls interrupts with a true INT call
  15. ;               ALTMSDOS        - calls DOS with a true INT call
  16. ;               CIRRUSCK        - Cirrus VGA check
  17. ;               CTICK           - Chips & Technologies VGA check
  18. ;               TSENGCK         - Tseng VGA check
  19. ;               ZYMOSCK         - ZyMOS VGA check
  20. ;               BUGTST          - Test for 386 POPAD bug
  21. ;
  22. ;       Originally by:
  23. ;       Steve Grant
  24. ;       Long Beach, CA
  25. ;       January 13, 1989
  26. ;
  27. ;       mods by Andrew Rossmann (6/26/93)
  28. ;--------------------------------------------------------------------
  29.  
  30. .286P
  31. .8087
  32.  
  33.         public  CPUID, DISKREAD, LONGCALL, ATIINFO, ALTINTR, ALTMSDOS
  34.         public  CTICK, TSENGCK, ZYMOSCK, CIRRUSCK, BUGTST
  35.  
  36. CODE    segment byte
  37.  
  38. ;       Conditional jumps are all coded with the SHORT qualifier in
  39. ;       order to minimize the size of the .OBJ file output of Turbo
  40. ;       Assembler.
  41.  
  42. ;--------------------------------------------------------------------
  43.  
  44. CPUID   proc    far
  45.  
  46. assume  cs:CODE, ds:DATA, es:nothing, ss:nothing
  47.  
  48. ;       On entry:
  49. ;
  50. ;               BP
  51. ;       SP =>   near return address
  52. ;               offset  of a cpu_info_t record
  53. ;               segment "  "     "        "
  54. ;       also, the test type byte should be a 'C' or 'N' to execute the
  55. ;       CPU or NDP tests.
  56. ;
  57. ;       On exit, the cpu_info_t record has been filled in as follows:
  58. ;
  59. ;               byte    = CPU type
  60. ;               word    = Machine Status Word
  61. ;               6 bytes = Global Descriptor Table
  62. ;               6 bytes = Interrupt Descriptor Table
  63. ;               boolean = segment register change/interrupt flag
  64. ;               byte    = NDP type
  65. ;               word    = NDP control word
  66. ;               byte    = Weitek presence
  67. ;               byte    = test type (C, N, or W)
  68.  
  69. cpu_info        equ     [bp + 6]
  70.  
  71. mCPU    equ     byte ptr [bx]
  72. mMSW    equ     word ptr [bx + 1]
  73. mGDT    equ     [bx + 3]
  74. mIDT    equ     [bx + 9]
  75. mchkint equ     byte ptr [bx + 15]
  76. mNDP    equ     byte ptr [bx + 16]
  77. mNDPCW  equ     word ptr [bx + 17]
  78. mWeitek equ     byte ptr [bx + 19]
  79. mtest   equ     byte ptr [bx + 20]
  80.  
  81. f8088   equ     0
  82. f8086   equ     1
  83. fV20    equ     2
  84. fV30    equ     3
  85. f80188  equ     4
  86. f80186  equ     5
  87. f80286  equ     6
  88. f80386  equ     7
  89. f80486  equ     8
  90. funk    =       0FFH
  91.  
  92. false   equ     0
  93. true    equ     1
  94.  
  95.         push    bp
  96.         mov     bp,sp
  97.         push    ds
  98.         lds     bx,cpu_info
  99.         cmp     mtest, 'C'
  100.         jnz     skipcpu
  101.         call    cpu
  102.         call    chkint
  103. skipcpu:
  104.         cmp     mtest, 'N'
  105.         jnz     skipndp
  106.         call    ndp
  107. skipndp:
  108.         cmp     mtest, 'W'
  109.         jnz     skipweitek
  110.         call    weitek
  111. skipweitek:
  112.         pop     ds
  113.         pop     bp
  114.         ret     4
  115. CPUID   endp
  116.  
  117. ;--------------------------------------------------------------------
  118.  
  119. cpu     proc    near
  120.  
  121. ; interrupt of multi-prefix string instruction
  122.  
  123.         mov     mCPU,funk               ;set CPU type to unknown
  124.         sti
  125.         mov     cx,0FFFFH
  126. rep     lods    byte ptr es:[si]
  127.         jcxz    short cpu_02
  128.         call    piq
  129.         cmp     dx,4
  130.         jg      short cpu_01
  131.         mov     mCPU,f8088
  132.         jmp     cpu_done
  133. cpu_01:
  134.         cmp     dx,6
  135.         jne     cpu_01a
  136.         mov     mCPU,f8086
  137. cpu_01a:
  138.         jmp     cpu_done
  139. cpu_02:
  140.  
  141. ; number of bits in displacement register used by shift
  142.  
  143.         mov     al,0FFH
  144.         mov     cl,20H
  145.         shl     al,cl
  146.         or      al,al
  147.         jnz     short cpu_04
  148.         call    piq
  149.         cmp     dx,4
  150.         jg      short cpu_03
  151.         mov     mCPU,fV20
  152.         jmp     cpu_done
  153. cpu_03:
  154.         cmp     dx,6
  155.         je      cpu_03a
  156.         jmp     cpu_done
  157. cpu_03a:
  158.         mov     mCPU,fV30
  159.         jmp     cpu_done
  160. cpu_04:
  161.  
  162. ; order of write/decrement by PUSH SP
  163.  
  164.         push    sp
  165.         pop     ax
  166.         cmp     ax,sp
  167.         je      short cpu_06
  168.         call    piq
  169.         cmp     dx,4
  170.         jg      short cpu_05
  171.         mov     mCPU,f80188
  172.         jmp     cpu_done
  173. cpu_05:
  174.         cmp     dx,6
  175.         jne     short cpu_done
  176.         mov     mCPU,f80186
  177.         jmp     cpu_done
  178.  
  179. ; We most likely have a 286, 386 or 486 CPU by now
  180. ;First, grab some tables
  181.  
  182. cpu_06:
  183.         smsw    mMSW
  184.         sgdt    mGDT
  185.         sidt    mIDT
  186.  
  187. ;!!!!!!!
  188. ;!!! Original 286/386 detection code (modified 8/10/90)
  189. ;!!! Modified by code supplied by John Levine, apparantly from an Intel
  190. ;!!! '486 manual.
  191. ;!!!!!!!
  192.  
  193.         pushf                           ;put flags into CX
  194.         pop     cx
  195.         and     cx,0fffh                ;mask off upper 4 bits
  196.         push    cx
  197.         popf
  198.         pushf
  199.         pop     ax
  200.         and     ax,0f000h               ;look only at upper 4 bits
  201.         cmp     ax,0f000h               ;88/86 etc.. turn them on
  202.         jz      badcpu                  ;not 286/386/486!!!
  203.         or      cx,0f000h               ;force upper 4 bits on
  204.         push    cx
  205.         popf
  206.         pushf
  207.         pop     ax
  208.         and     ax,0f000h
  209.         jz      found286                ;bits are zeroed in real mode 286
  210. ;
  211. ;since we probably have have a 386 or 486 by now, we need to do some 32-bit
  212. ;work. Detect the 486 by seeing if the Alignment Check flag is settable. This
  213. ;flag only exists on the '486.
  214. ;
  215. .386
  216.         and     esp,0FFFFh              ;use only 64K stack
  217.         mov     edx,esp                 ;save current stack position
  218.         and     esp,0FFFCh              ;dword align to avoid traps
  219.         pushfd                          ;push 32 bit flag
  220.         pop     eax
  221.         mov     ecx,eax                 ;save current flags
  222.         xor     eax,40000h              ;flip AC (alignment check) flag
  223.         push    eax
  224.         popfd
  225.         pushfd
  226.         pop     eax
  227.         xor     eax,ecx                 ;eliminate all but AC bit
  228.         push    ecx                     ;restore flags
  229.         popfd
  230.         mov     esp,edx                 ;restore stack position
  231.         test    eax,40000h              ;is bit set?
  232. .286
  233.         jz      found386                ;if not, is a 386
  234.         mov     mCPU,f80486             ;must be a 486!!
  235.         jmp     short cpu_done
  236. found286:
  237.         mov     mCPU,f80286
  238.         jmp     short cpu_done
  239. found386:
  240.         mov     mCPU,f80386
  241.         jmp     short cpu_done
  242. badcpu:
  243.         mov     mCPU,funk               ;how'd an 8088 get this far?????
  244. CPU_done:
  245.         ret
  246. cpu     endp
  247. ;--------------------------------------------------------------------
  248.  
  249. piq     proc    near
  250.  
  251. ;       On exit:
  252. ;
  253. ;               DX      = length of prefetch instruction queue
  254. ;
  255. ;       This subroutine uses self-modifying code, but can
  256. ;       nevertheless be run repeatedly in the course of the calling
  257. ;       program.
  258.  
  259. count   =       7
  260. opincdx equ     42H                     ; inc dx opcode
  261. opnop   equ     90H                     ; nop opcode
  262.  
  263.         mov     al,opincdx
  264.         mov     cx,count
  265.         push    cx
  266.         push    cs
  267.         pop     es
  268.         mov     di,offset piq_01 - 1
  269.         push    di
  270.         std
  271.         rep stosb
  272.         mov     al,opnop
  273.         pop     di
  274.         pop     cx
  275.         xor     dx,dx
  276.         cli
  277.         rep stosb
  278.         rept    count
  279.         inc     dx
  280.         endm
  281. piq_01:
  282.         sti
  283.         ret
  284. piq     endp
  285.  
  286. ;--------------------------------------------------------------------
  287.  
  288. chkint  proc    near
  289.  
  290. ; save old INT 01H vector
  291.  
  292.